<?php
// +----------------------------------------------------------------------
// | RXThinkCMF敏捷开发框架 [ 赋能开发者，助力企业发展 ]
// +----------------------------------------------------------------------
// | 版权所有 2018~2023 南京RXThinkCMF研发中心
// +----------------------------------------------------------------------
// | Licensed LGPL-3.0 RXThinkCMF并不是自由软件，未经许可禁止去掉相关版权
// +----------------------------------------------------------------------
// | 官方网站: https://www.rxthink.cn
// +----------------------------------------------------------------------
// | Author: @牧羊人 团队荣誉出品
// +----------------------------------------------------------------------
// | 版权和免责声明:
// | 本团队对该软件框架产品拥有知识产权（包括但不限于商标权、专利权、著作权、商业秘密等）
// | 均受到相关法律法规的保护，任何个人、组织和单位不得在未经本团队书面授权的情况下对所授权
// | 软件框架产品本身申请相关的知识产权，禁止用于任何违法、侵害他人合法权益等恶意的行为，禁
// | 止用于任何违反我国法律法规的一切项目研发，任何个人、组织和单位用于项目研发而产生的任何
// | 意外、疏忽、合约毁坏、诽谤、版权或知识产权侵犯及其造成的损失 (包括但不限于直接、间接、
// | 附带或衍生的损失等)，本团队不承担任何法律责任，本软件框架禁止任何单位和个人、组织用于
// | 任何违法、侵害他人合法利益等恶意的行为，如有发现违规、违法的犯罪行为，本团队将无条件配
// | 合公安机关调查取证同时保留一切以法律手段起诉的权利，本软件框架只能用于公司和个人内部的
// | 法律所允许的合法合规的软件产品研发，详细声明内容请阅读《框架免责声明》附件；
// +----------------------------------------------------------------------

namespace app\admin\service;

use AmapService;
use app\admin\model\Schoole;
use think\Db;

/**
 * 学校管理-服务类
 * @author 牧羊人
 * @since: 2024/06/25
 * Class StudentService
 * @package app\admin\service
 */
class SchooleService extends BaseService
{
    protected $userId = 0;
    /**
     * 构造函数
     * LevelService constructor.
     */
    public function __construct()
    {
        $this->model = new Schoole();
        // 解析Token获取用户ID
        $token = request()->header("Authorization");
        $token = str_replace("Bearer ", null, $token);
        $jwt = new \Jwt();
        $this->userId = $jwt->verifyToken($token);
    }

    /**
     * 删除记录
     * @return array
     * @since 2020/11/12
     * @author 牧羊人
     */
    public function delete()
    {
        // 参数
        $param = request()->param();

        // 记录ID
        $ids = $param['id'];
        if (empty($ids)) {
            return message("记录ID不能为空", false);
        }
        foreach($ids as $id){
            $row1 = Db::table('think_teacher')->where('schoole_id',$id)->where('mark',1)->find();
            if($row1){
                return message("学校有老师，不允许删除", false);
            }
            $row = Db::table('think_grade')->where('schoole_id',$id)->where('mark',1)->find();
            if($row){
                $s = Db::table('think_schoole')->find($id);
                return message($s['title']."有年级，不允许删除", false);
            }

        }

        if (is_array($ids)) {
            // 批量删除
            $result = $this->model->deleteDAll($ids);
            if (!$result) {
                return message("批量删除失败", false);
            }

            return message("批量删除成功");
        } else {
            // 单个删除
            $result = $this->model->drop($ids);
            if (!$result) {
                return message('删除失败', false);
            }

            return message('删除成功');
        }
    }


    /**
     * 获取数据列表
     * @return array
     * @since 2024/06/25
     * @author 牧羊人
     */
    public function getList($page = 0, $limit = 0)
    {
        $param = request()->param();

        // 获取参数值
        $province_code = getter($param, "province_code");
        $city_code = getter($param, "city_code");
        $district_code = getter($param, "district_code");
        $streets_code = getter($param, "streets_code");
        $title = getter($param, "title");

        // 查询条件
        $map = [];

        if ($streets_code) {
            $map[] = ['streets_code', '=', $streets_code];
        } elseif ($district_code) {
            $map[] = ['district_code', '=', $district_code];
        } elseif ($city_code) {
            $map[] = ['city_code', '=', $city_code];
        } elseif ($province_code) {
            $map[] = ['province_code', '=', $province_code];
        } else if ($title) {
            $map[] = ['title', 'like', '%' . $title . '%'];
        }

        $map[] = ['mark', '=', 1];  //有效标识 = 1

        $sort = 'sort desc,id desc';

        $page = $page ?: request()->param('page', 1);
        $limit = $limit ?: request()->param('limit', 20);

        $teacher = getTeacher($this->userId);
        if($teacher){
            $map[] = ['id', '=', $teacher['schoole_id']];
        }
        $schoolRole = SchoolRoleMap($this->userId);
        if($schoolRole){
            $map[] = $schoolRole;
        }

        $query = $this->model->with(['province', 'city', 'district', 'streets'])->where($map);
        $count = $query->count();
        $list = $query->order($sort)->page($page, $limit)->select();

        $res = [
            "msg" => '获取成功',
            "code" => 0,
            "count" => $count,
            "data" => $list,
        ];

        return $res;
    }

    /**
     * 添加或编辑
     * @return mixed
     * @since 2020/11/20
     * @author 牧羊人
     */
    public function edit()
    {
        // 请求参数
        $data = request()->param();

        // 城市数据处理
        $data['province_code'] = $data['city_code'] = $data['district_code'] = $data['streets_code'] = 0;
        if (isset($data['city']) && $data['city']) {
            $data['province_code'] = $data['city'][0];
            $data['city_code'] = $data['city'][1];
            $data['district_code'] = $data['city'][2];
            $data['streets_code'] = $data['city'][3];

            unset($data['city']);
        }

        //权限判断
        $userId = ($this->model)::$staticUserId;
        $map[] = ['user_id', '=', $userId];
        $map[] = ['role_id', 'in', [1,2,5,6,7]];
        $role_ids = db('user_role')->where($map)->column('role_id');
        if(!$role_ids) return message("您没有权限操作", false);

        //各级别管理员只能操作自己辖区的学校
        $uinfo = db('user')->where(['id' => $userId])->find();
        if(in_array(5, $role_ids) && $uinfo['city_code']!= $data['city_code']){//市级管理员
             return message("只可以操作自己辖区的学校", false);
        }
        if(in_array(6, $role_ids) && $uinfo['district_code']!= $data['district_code']){//区级管理员
             return message("只可以操作自己辖区的学校", false);
        }
        if(in_array(7, $role_ids) && $uinfo['streets_code']!= $data['streets_code']){//街道级管理员
             return message("只可以操作自己辖区的学校", false);
        }

        $amap = new AmapService();
        $amapResult = $amap->geocode($data['location']);  //逆地理编码的location格式为经度在前，纬度在后
        if (isset($amapResult['status']) && $amapResult['status'] == 1) {
            $data['location'] = $amapResult['geocodes'][0]['location'];
        } else {
            $data['location'] = '';
        }

        return parent::edit($data); // TODO: Change the autogenerated stub
    }

    /**
     * 导入Excel
     */
    public function importExcel()
    {
        //学校
        $schoole_id = request()->param('schoole_id', '');
        if (!$schoole_id)
            return message("缺少schoole_id", false);
        if (!db('schoole')->where(['id' => $schoole_id])->value('id'))
            return message("学校不存在", false);

        // 检查文件扩展名
        $file = $_FILES['file'];;
        if (!$file) return message("请上传文件", false);
        $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
        if (strtolower($extension) !== 'xlsx')
            return message("上传的文件必须是 .xlsx 格式。", false);

        $error = "";
        // 上传文件(非图片)
        $result = upload_file('file', 'student/import/', $error);
        if (!$result) {
            return message($error, false);
        }
        // 文件路径
        $filePath = IMG_PATH . $result;
        if (!file_exists($filePath)) {
            return message("文件不存在", false);
        }
        // 读取文件
        $objPHPExcel = \PHPExcel_IOFactory::load($filePath); //获取sheet表格数目
        $sheetSelected = 0;
        $objPHPExcel->setActiveSheetIndex($sheetSelected); //获取表格行数
        $activeSheet = $objPHPExcel->getActiveSheet();
        $rowCount = $activeSheet->getHighestRow(); //获取表格列数
        $columnCount = $activeSheet->getHighestColumn();
        $totalNum = $rowCount - 2;
        //验证文件内容
        if ($totalNum < 1) return message("请填写数据后上传", false);
        if ($columnCount != 'J') return message("请不要更改模板文件格式，填写数据后上传", false);

        $dataArr = array();
        $gender_arr = [
            '男' => 1,
            '女' => 2,
        ];
        $imei_arr = [];
        // 循环读取行数据
        for ($row = 3; $row <= $rowCount; $row++) {
            // 获取列值
            $imei = trim($activeSheet->getCell("I" . $row)->getValue());
            if (!$imei) return message(sprintf('第%s行，设备IMEI未填写', $row), false);
            $imei_id = db('device_imei')->where(['imei' => $imei])->value('id');
            if (!$imei_id) return message(sprintf('第%s行，设备IMEI：%s 不存在', $row, $imei), false);
            $student_id = db('student')->where(['imei' => $imei])->value('id');
            if ($student_id) return message(sprintf('第%s行，设备IMEI：%s 已绑定学生', $row, $imei), false);
            if (in_array($imei, array_keys($imei_arr)))
                return message(sprintf('第%s行，设备IMEI：%s ，与第%s行重复', $row, $imei, $imei_arr[$imei]), false);
            $imei_arr[$imei] = $row;

            //年级
            $grade_id = 0;
            $grade = trim($activeSheet->getCell("E" . $row)->getValue());
            if ($grade) {
                $grade_id = db('grade')->where(['schoole_id' => $schoole_id, 'title' => $grade])->value('id');
                if (!$grade_id) return message(sprintf('第%s行，年级：%s 不存在', $row, $grade), false);
            }
            //班级
            $class_id = 0;
            $class = trim($activeSheet->getCell("F" . $row)->getValue());
            if ($class) {
                $class_id = db('class')->where(['schoole_id' => $schoole_id, 'grade_id' => $grade_id, 'title' => $class])->value('id');
                if (!$class_id) return message(sprintf('第%s行，班级：%s 不存在', $row, $class), false);
            }

            $name = trim($activeSheet->getCell("A" . $row)->getValue());
            $student_no = trim($activeSheet->getCell("B" . $row)->getValue());
            $id_card = trim($activeSheet->getCell("C" . $row)->getValue());
            $gender = trim($activeSheet->getCell("D" . $row)->getValue());
            $gender = $gender_arr[$gender] ?? 0;
            $phone = trim($activeSheet->getCell("G" . $row)->getValue());
            $relatives_phone = trim($activeSheet->getCell("H" . $row)->getValue());
            $sim_no = trim($activeSheet->getCell("J" . $row)->getValue());
            if ($id_card && strlen($id_card) != 18) return message(sprintf('第%s行，身份证号：%s 格式错误', $row, $id_card), false);
            if ($phone && strlen($phone) != 11) return message(sprintf('第%s行，手机号：%s 格式错误', $row, $phone), false);
            if ($relatives_phone && strlen($relatives_phone) != 11) return message(sprintf('第%s行，紧急联系人手机号：%s 格式错误', $row, $relatives_phone), false);

            $dataArr[] = compact('imei', 'name', 'student_no', 'id_card', 'gender', 'grade_id', 'class_id', 'schoole_id', 'phone', 'relatives_phone', 'sim_no');
        }

        Db::startTrans();
        try {
            $this->model->saveAll($dataArr);
            Db::commit();
        } catch (\Throwable $e) {
            Db::rollback();
            trace('导入学生异常：' . $e->getTraceAsString(), 'error');
            return message($e->getMessage(), false);
        }
        return message("本次成功导入{$totalNum}条数据", true);
    }

    /**
     * 导出Excel
     * @throws \PHPExcel_Exception
     * @throws \PHPExcel_Reader_Exception
     * @throws \PHPExcel_Writer_Exception
     */
    public function exportExcel()
    {
        set_time_limit(0);
        $export_type = request()->param('export_type', 0);
        $schoole_id = request()->param('schoole_id', '');
        $schoole_name = '';

        // 获取导出的数据源
        $res = $this->getList(1, 20000);
        $list = $res['data'];

        // 实例化PHPExcel类
        $objPHPExcel = new \PHPExcel();
        // 激活当前的sheet表
        $activeSheet = $objPHPExcel->setActiveSheetIndex(0);
        //5.设置表格头（即excel表格的第一行）
        $activeSheet->setCellValue('A1', '姓名')
            ->setCellValue('B1', '学号')
            ->setCellValue('C1', '身份证号')
            ->setCellValue('D1', '性别')
            ->setCellValue('E1', '学校')
            ->setCellValue('F1', '年级')
            ->setCellValue('G1', '班级')
            ->setCellValue('H1', '电话')
            ->setCellValue('I1', '紧急联系人电话')
            ->setCellValue('J1', '设备IMEI')
            ->setCellValue('K1', 'SIM卡号')
            ->setCellValue('L1', '创建时间');

        // 设置单元格宽度
        $activeSheet->getColumnDimension('A')->setWidth(20);
        $activeSheet->getColumnDimension('B')->setWidth(20);
        $activeSheet->getColumnDimension('C')->setWidth(20);
        $activeSheet->getColumnDimension('D')->setWidth(20);
        $activeSheet->getColumnDimension('E')->setWidth(20);
        $activeSheet->getColumnDimension('F')->setWidth(20);
        $activeSheet->getColumnDimension('G')->setWidth(20);
        $activeSheet->getColumnDimension('H')->setWidth(20);
        $activeSheet->getColumnDimension('I')->setWidth(20);
        $activeSheet->getColumnDimension('J')->setWidth(20);
        $activeSheet->getColumnDimension('K')->setWidth(20);
        $activeSheet->getColumnDimension('L')->setWidth(20);

        //'s.*, schoole.title as schoole_name, grade.title as grade_name, class.title as class_name'
        // 循环刚取出来的数组，将数据逐一添加到excel表格
        $gender_arr = [
            '1' => '男',
            '2' => '女',
        ];
        for ($i = 0; $i < count($list); $i++) {
            $gender = $gender_arr[$list[$i]['gender']] ?? '';
            $activeSheet->setCellValue('A' . ($i + 2), $list[$i]['name']);
            $activeSheet->setCellValue('B' . ($i + 2), $list[$i]['student_no']);
            $activeSheet->setCellValue('C' . ($i + 2), $list[$i]['id_card']);
            $activeSheet->setCellValue('D' . ($i + 2), $gender);
            $activeSheet->setCellValue('E' . ($i + 2), $list[$i]['schoole_name']);
            $activeSheet->setCellValue('F' . ($i + 2), $list[$i]['grade_name']);
            $activeSheet->setCellValue('G' . ($i + 2), $list[$i]['class_name']);
            $activeSheet->setCellValue('H' . ($i + 2), $list[$i]['phone']);
            $activeSheet->setCellValue('I' . ($i + 2), $list[$i]['relatives_phone']);
            $activeSheet->setCellValue('J' . ($i + 2), $list[$i]['imei']);
            $activeSheet->setCellValue('K' . ($i + 2), $list[$i]['sim_no']);
            $activeSheet->setCellValue('L' . ($i + 2), date('Y-m-d H:i:s', $list[$i]['create_time']));
            $schoole_name = $list[$i]['schoole_name'];
        }
        // 设置保存的Excel表格名称
        $filename = $schoole_name . '_学生导出_' . date('YmdHis', time()) . ".xlsx";
        // 设置当前激活的sheet表格名称
        $activeSheet->setTitle('Sheet1');

        if ($export_type) { //直接浏览器输出
            header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
            header('Content-Disposition: attachment;filename="' . $filename);
            header('Cache-Control: max-age=0');
            // If you're serving to IE 9, then the following may be needed
            header('Cache-Control: max-age=1');
            // If you're serving to IE over SSL, then the following may be needed
            header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
            header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
            header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
            header('Pragma: public'); // HTTP/1.0
            $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
            $objWriter->save('php://output');
            return;
        }

        // 保存本地文件
        $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
        $file_dir = UPLOAD_TEMP_PATH . "/" . $schoole_id . "/";
        $savePath = $file_dir . $filename;
        // 检测文件路径是否存在,不存在则创建
        if (!file_exists($file_dir)) {
            mkdirs($file_dir, 0777, true);
        }
        $objWriter->save($savePath);

        // 文件地址
        $filePath = get_image_url(str_replace(PUBLIC_PATH, "", $savePath));
        return message("操作成功", true, $filePath);
    }
}
